/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/


#include "stdafx.h"
#include <pgl/mfc/PGLDialog.h>
#include <pgl/mfc/PGLDialogList.h>
#include <pgl/core/PGLAllPropsDlg.h>
#include "ImgPropDialog.h"
#include <pgl/mfc/PGLMFCGlobal.h>
#include <pgl/mfc/PGLPanEvent.h>
#include <pgl/mfc/PGLZoomEvent.h>
#include <pgl/mfc/PGLZoomRegionEvent.h>
#include <pgl/mfc/PGLDefaultEvent.h>
#include "..\pgl\mfc\pgldialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// CPGLDialog dialog


CPGLDialog::CPGLDialog(CWnd* pParent, CPGLRegionPtr _pRegion , DWORD dwFlags)
: CDialogEx(IDD_PGL_DIALOG_GRAPH, pParent ), m_uPointedRegion(0), m_pRegion(_pRegion), 
	m_GDIpHelper(&m_GDIpInterface, m_pRegion), m_pDialogManager(NULL), m_dwFlags(dwFlags),
	m_archive(_pRegion,&m_GDIpInterface)
{
	//{{AFX_DATA_INIT(CPGLDialog)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}

CPGLDialog::~CPGLDialog()
{
	ClearEvent();
	CleanRegion();
}

void CPGLDialog::CleanRegion()
{
	m_pRegion.reset();
}

void CPGLDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPGLDialog)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CPGLDialog, CDialogEx)
	//{{AFX_MSG_MAP(CPGLDialog)
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_COMMAND(ID_PGL_FIGURE_SAVEAS, OnFileExport)
	ON_COMMAND(ID_PGL_EDIT_CUT, OnEditCut)
	ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
	ON_COMMAND(ID_PGL_EDIT_PASTE, OnEditPaste)
	ON_COMMAND(ID_PGL_EDIT_DELETE, OnEditDelete)
	ON_COMMAND(ID_PGL_SELECTION_ORDER_MOVEDOWN, OnSelectionOrderMovedown)
	ON_COMMAND(ID_PGL_SELECTION_ORDER_MOVEUP, OnSelectionOrderMoveup)
	ON_COMMAND(ID_PGL_SELECTION_ORDER_TOBACK, OnSelectionOrderToback)
	ON_COMMAND(ID_PGL_SELECTION_ORDER_TOFRONT, OnSelectionOrderTofront)
	ON_COMMAND(ID_PGL_SELECTION_SELECTALL, OnSelectionSelectall)
	ON_COMMAND(ID_PGL_SELECTION_UNHIDEALL, OnSelectionUnhideall)
	ON_COMMAND(ID_PGL_SELECTION_UNSELECT, OnSelectionUnselect)
	ON_COMMAND(ID_PGL_VIEW_SELECT, OnViewSelect)
	ON_COMMAND(ID_PGL_VIEW_PAN, OnViewPan)
	ON_COMMAND(ID_PGL_VIEW_PROPERTIES, OnViewProperties)
	ON_COMMAND(ID_PGL_VIEW_ZOOM, OnViewZoom)
	ON_COMMAND(ID_PGL_VIEW_ZOOMBOX, OnViewZoombox)
	ON_COMMAND(ID_PGL_VIEW_ZOOMALL, OnViewZoomAll)
	ON_WM_CLOSE()
	ON_WM_DESTROY()
	ON_COMMAND(ID_PGL_FILE_SAVE, OnFileSave)
	ON_COMMAND(ID_PGL_FILE_OPEN, OnFileOpen)
	ON_WM_MOUSEMOVE()
	ON_UPDATE_COMMAND_UI(ID_PGL_VIEW_ZOOMBOX, OnUpdatePglViewZoombox)
	ON_UPDATE_COMMAND_UI(ID_PGL_VIEW_ZOOM, OnUpdatePglViewZoom)
	ON_UPDATE_COMMAND_UI(ID_PGL_VIEW_PAN, OnUpdatePglViewPan)
	ON_COMMAND(ID_PGL_FILE_PRINT, OnFilePrint)
	ON_COMMAND(ID_PGL_EDIT_COPYTOCLIPBOARD, OnEditCopytoclipboard)
	ON_COMMAND(ID_PGL_VIEW_REFRESHAXIS, OnViewRefreshaxis)
	ON_COMMAND(ID_PGL_CLIPBOARDTYPE_BITMAP, OnClipboardtypeBitmap)
	ON_COMMAND(ID_PGL_CLIPBOARDTYPE_METAFILE, OnClipboardtypeMetafile)
	ON_UPDATE_COMMAND_UI(ID_PGL_CLIPBOARDTYPE_BITMAP, OnUpdateClipboardtypeBitmap)
	ON_UPDATE_COMMAND_UI(ID_PGL_CLIPBOARDTYPE_METAFILE, OnUpdateClipboardtypeMetafile)
	ON_COMMAND(ID_VIEW_ANTIALIASING_TEXT, OnViewAntialiasingText)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ANTIALIASING_TEXT, OnUpdateViewAntialiasingText)
	ON_COMMAND(ID_VIEW_ANTIALIASING_GRAPHICS, OnViewAntialiasingGraphics)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ANTIALIASING_GRAPHICS, OnUpdateViewAntialiasingGraphics)
	ON_COMMAND(ID_VIEW_ANTIALIASING_CUBICTEXTUREINTERPOLATION, OnViewAntialiasingCubictextureinterpolation)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ANTIALIASING_CUBICTEXTUREINTERPOLATION, OnUpdateViewAntialiasingCubictextureinterpolation)
	ON_WM_LBUTTONDBLCLK()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_WM_MOUSEWHEEL()
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
	ON_WM_RBUTTONDBLCLK()
	ON_WM_RBUTTONUP()
	ON_COMMAND(ID_FIGURE_IMPORTCSVFILE, OnFigureImportcsvfile)
	ON_COMMAND(ID_EDIT_CLEARCHART, OnEditClearchart)
	ON_COMMAND(ID_PGL_EDIT_COPY, OnEditCopy)
	ON_COMMAND(ID_ABOUT_ABOUT, OnAboutAbout)
	//}}AFX_MSG_MAP
    ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

//	ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
//	ON_COMMAND(ID_FILE_PRINT_DIRECT, OnFilePrint)
//	ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)

void CPGLDialog::SetDirty()
{
	m_GDIpHelper.SetDirty();
	InvalidateRect(NULL,FALSE);
};


void CPGLDialog::SetTripleBuffering(bool on)
{
	m_GDIpHelper.SetTripleBuffering(on);
	InvalidateRect(NULL,FALSE);
}

void CPGLDialog::SetFrontDirty()
{
	m_GDIpHelper.SetFrontDirty();
	InvalidateRect(NULL,FALSE);
};

void CPGLDialog::SetCacheDirty()
{
	m_GDIpHelper.SetCacheDirty();
	InvalidateRect(NULL,FALSE);
};

/////////////////////////////////////////////////////////////////////////////
// CPGLDialog message handlers

BOOL CPGLDialog::OnInitDialog() 
{
	PGL_TRACE(_T("PGL-GraphBitDlg: Initialisating graph\n"));

	CDialogEx::OnInitDialog();

	HMODULE hInst = CPGLMFCGlobal::GetInstance();
	ASSERT(hInst);

	////////////////////////////////////////////////////////////////////////////////////////////
	// Menu customization
	// loading toolbar in menu
	#ifndef PGL_NO_NEWMENU
		m_DefaultNewMenu.LoadToolBar(IDR_PGL_DIALOG_TOOLBAR, hInst );
	#endif

	UINT pIndicators[] = { ID_SEPARATOR,
		ID_PGL_POINTEDREGION,
		ID_PGL_MOUSEPOSITION,
		ID_PGL_MOUSEPOSITION_WORLD,
//		ID_PGL_MOUSEPOSITION_NORM,
//		ID_PGL_MOUSEPOSITION_NORMCLIP,
		ID_PGL_CLIENTSIZE};


	if (! InitDialogEx( 
        hInst , 
        TRUE, 
        !(m_dwFlags & OptionNoTaskBar), 
        pIndicators, 
        5, 
        IDR_PGL_DIALOG_TOOLBAR,
		(m_dwFlags & OptionNoToolBar) ? 0 : TBSTYLE_FLAT  | WS_CHILD | WS_VISIBLE | CBRS_FLYBY | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS) 
        )
	return -1;

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	m_hIcon=LoadIcon(CPGLCoreGlobal::GetInstance(), MAKEINTRESOURCE(IDI_PGL_ICON));

	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// enable triple buffering
	if (m_dwFlags & OptionTripleBuffering)
	{
		m_GDIpHelper.SetTripleBuffering(true);
	}


	if (m_dwFlags && OptionClipboardMetafile)
		m_eClipboardType = CPGLArchive::ClipBoardMetafile;
	else
		m_eClipboardType = CPGLArchive::ClipBoardBitmap;

	if (!m_pRegion)
		return FALSE;
		
	PostResize();

	if (m_pRegion && !(m_dwFlags & OptionNoZoomAll))
	{
		CClientDC dc(this);
		Gdiplus::Graphics graphics(dc.m_hDC);
		m_GDIpInterface.SetGraphics(&graphics);
		m_GDIpInterface.BeginPaint(dc.m_hDC);
			m_pRegion->ZoomAll(m_GDIpInterface,true);
		m_GDIpInterface.EndPaint();	
	}	

	SetEvent( CPGLEventPtr(new CPGLDefaultEvent) );

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CPGLDialog::OnPaint() 
{	
	using namespace Gdiplus;
	// Create and set an array of real numbers.
	CRect rect;
	CClientDC dc(this);

	// Init graph DC
	if (IsIconic())
	{
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{	
		if (!m_pRegion)
			return;

		// changing window name
		SetWindowText(m_pRegion->GetLegendString());
		// blitting...
		if (GetUpdateRect(&rect))
		{
			CPaintDC paintDC(this);

			CRect clientRect;
			GetClientRectEx(clientRect);
			if((clientRect.Width() <= 0) || (clientRect.Height() <= 0) || !m_pRegion)
				return ; // nothing to do here....

			Graphics graphics(paintDC.m_hDC);

            try
            {
			if (IsResizeNeeded())
			{
				//Getting real size of client...
				CRect rect, rectWnd;
				GetClientRect(rectWnd);
				GetClientRectEx(rect);

				rect.top = rectWnd.Height() - rect.top;
				rect.bottom = rectWnd.Height() - rect.bottom;

				if ( abs(rect.Width())>0 && abs(rect.Height()) > 0)
				{
					m_GDIpInterface.SetGraphics(&graphics);
					m_GDIpInterface.BeginPaint(dc.m_hDC);
						m_GDIpInterface.SetMainBoundingBox(rect);
						m_pRegion->SetViewport(rect.left, rect.bottom , rect.Width(), abs(rect.Height()));
						m_pRegion->RefreshView(m_GDIpInterface,true);
					m_GDIpInterface.EndPaint();
				}

				ResetResizeState();
			}

			m_GDIpHelper.Draw(clientRect, paintDC.m_hDC, &graphics);

			if (m_pEvent)
				m_pEvent->Draw(graphics, clientRect);

            }
            catch(std::exception& e_)
            {
                CString s;
                s.Format(_T("An exception has occured: %s"), e_.what());
                AfxMessageBox(s);
            }

		}
	}
}

void CPGLDialog::OnSize(UINT nType, int cx, int cy) 
{
	using namespace Gdiplus;

	CDialogEx::OnSize(nType, cx, cy);

	PGL_TRACE(_T("PGL-GraphBitDlg: Resizing graph\n"));

	if (cx && cy && m_pRegion)
	{
		SetDirty();
		PostResize();
		UpdateStatusBar();
	}

}

void CPGLDialog::OnLButtonDown(UINT nFlags, CPoint point) 
{
	ClientToClientEx(&point);

	if (!m_pRegion)
		return;

	// keeping mouse
	SetCapture();

	CPGLPointD pglPoint( point.x, point.y);
	m_uPointedRegion = m_pRegion->FindPointedRegion( m_GDIpInterface, pglPoint);	

	// mouse is down
	m_mouse.LeftBtnPressed(point.x, point.y);
	m_mouse.Stop();

	// handling event
	if (m_pEvent)
	{
		m_pEvent->SetRegion(m_uPointedRegion);
		m_pEvent->OnLButtonDown(nFlags,point);
	}

	// end
	CDialogEx::OnLButtonDown(nFlags, point);
}

void CPGLDialog::OnRButtonDown(UINT nFlags, CPoint point) 
{
	if (!m_pRegion)
		return;

	ClientToClientEx(&point);

	// keeping mouse
	SetCapture();

	CPGLPointD pglPoint( point.x, point.y);
	m_uPointedRegion = m_pRegion->FindPointedRegion( m_GDIpInterface, pglPoint);	

	// mouse is down
	m_mouse.RightBtnPressed(point.x, point.y);
	m_mouse.Stop();

	// handling event
	if (m_pEvent)
	{
		m_pEvent->SetRegion(m_uPointedRegion);
		m_pEvent->OnRButtonDown(nFlags,point);
	}

	// end
	CDialogEx::OnLButtonDown(nFlags, point);
}


void CPGLDialog::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if (!m_pRegion)
		return;

	ClientToClientEx(&point);

	//Releasing mouse
	ReleaseCapture();

	// stop mouse...
	m_mouse.Stop();
	m_mouse.Move(point.x,point.y);

	// handling event
	if (m_pEvent)
	{
		m_pEvent->SetRegion(m_uPointedRegion);
		m_pEvent->OnLButtonUp(nFlags, point);
	}

	m_mouse.LeftBtnReleased();

	CDialogEx::OnLButtonUp(nFlags, point);
}


void CPGLDialog::OnRButtonUp(UINT nFlags, CPoint point) 
{
	ClientToClientEx(&point);

	//Releasing mouse
	ReleaseCapture();

	// stop mouse...
	m_mouse.Stop();
	m_mouse.Move(point.x,point.y);

	// handling event
	if (m_pEvent)
	{
		m_pEvent->SetRegion(m_uPointedRegion);
		m_pEvent->OnRButtonUp(nFlags, point);
	}

	m_mouse.RightBtnReleased();

	CDialogEx::OnLButtonUp(nFlags, point);
}

void CPGLDialog::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// handling event
	if (m_pEvent)
		m_pEvent->OnLButtonDblClk(nFlags, point);
	
	CDialogEx::OnLButtonDblClk(nFlags, point);
}

void CPGLDialog::OnRButtonDblClk(UINT nFlags, CPoint point) 
{
	// handling event
	if (m_pEvent)
		m_pEvent->OnRButtonDblClk(nFlags, point);
	
	CDialogEx::OnRButtonDblClk(nFlags, point);
}


void CPGLDialog::OnMouseMove(UINT nFlags, CPoint point) 
{
	int lastx,lasty;

	if (!m_pRegion)
	{
		CDialogEx::OnMouseMove(nFlags, point);
		return;
	}

	ClientToClientEx(&point);

	// no buttons down, finding region
	if (!m_mouse.IsLeftBtnDown(lastx,lasty) && !m_mouse.IsRightBtnDown(lastx,lasty))
	{
		// find pointed region...
		CPGLPointD pglPoint( point.x, point.y);
		m_uPointedRegion = m_pRegion->FindPointedRegion( m_GDIpInterface, pglPoint);	
	}


	if (m_mouse.IsLeftBtnDown(lastx,lasty))
		m_mouse.LeftMove();
	if (m_mouse.IsRightBtnDown(lastx,lasty))
		m_mouse.RightMove();


	// now update status bar
	UpdateStatusBar();

	// handling event
	if (m_pEvent)
	{
		m_pEvent->SetRegion(m_uPointedRegion);
		m_pEvent->OnMouseMove(nFlags,point);
	}

	// update mouse
	m_mouse.Move(point.x,point.y);
	
	CDialogEx::OnMouseMove(nFlags, point);
}

//////////////////////////////////////////////////////////////////
// Figure menu Callbacks
//////////////////////////////////////////////////////////////////

void CPGLDialog::OnFileExport() 
{
	using namespace Gdiplus;
	CString str, strFileName;

	if (!m_pRegion)
	{
		AfxMessageBox(_T("No plot to save"));
		return;
	}

	// pFileDlg...
	CFileDialog pFileDlg(
		FALSE /* open */,
		NULL	/* default extension */,
		_T("untitled")	/* initial pFilename in name box*/,
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		CPGLArchive::GetFileDialogFilter());

	// Getting pFile name
	if (pFileDlg.DoModal()!=IDOK)
		return;

	strFileName=pFileDlg.GetPathName();


	CRect rect;
	GetClientRectEx(rect);

	CClientDC dc(this);

	CImgPropDialog dlg(this, dc.GetSafeHdc(), rect, m_pRegion, 
		(CPGLArchive::EFileFormat)pFileDlg.m_ofn.nFilterIndex, strFileName);

	dlg.DoModal();

	// reseting size...
	GetClientRect(&rect);
	OnSize(SIZE_RESTORED, rect.Width(), rect.Height());
}

//////////////////////////////////////////////////////////////////
// Edit menu Callbacks
//////////////////////////////////////////////////////////////////
void CPGLDialog::OnEditCut() 
{

//	m_pRegion->CutSelection(); 
	InvalidateRect(NULL,FALSE);
}

void CPGLDialog::OnEditCopy() 
{
//	m_pRegion->CopySelection();
	InvalidateRect(NULL,FALSE);
}

void CPGLDialog::OnEditPaste() 
{

//	m_pRegion->PasteSelection();
	InvalidateRect(NULL,FALSE);
}

void CPGLDialog::OnEditDelete() 
{

//	m_pRegion->DeleteSelection();
	InvalidateRect(NULL,FALSE);
}

//////////////////////////////////////////////////////////////////
// Selection menu Callbacks
//////////////////////////////////////////////////////////////////

void CPGLDialog::OnSelectionOrderMovedown() 
{
	// TODO: Add your command handler code here
	
}

void CPGLDialog::OnSelectionOrderMoveup() 
{
	// TODO: Add your command handler code here
	
}

void CPGLDialog::OnSelectionOrderToback() 
{
	// TODO: Add your command handler code here
	
}

void CPGLDialog::OnSelectionOrderTofront() 
{
	// TODO: Add your command handler code here
	
}

void CPGLDialog::OnSelectionSelectall() 
{

//	m_pRegion->SelectAll();
	InvalidateRect(NULL,FALSE);
}

void CPGLDialog::OnSelectionUnhideall() 
{

	m_pRegion->UnhideAll();
	InvalidateRect(NULL,FALSE);
}

void CPGLDialog::OnSelectionUnselect() 
{

	InvalidateRect(NULL,FALSE);
}


void CPGLDialog::OnViewSelect() 
{
	ClearEvent();
}

void CPGLDialog::OnViewPan() 
{
	ClearEvent();

	SetEvent( CPGLEventPtr(new CPGLPanEvent));
}


void CPGLDialog::OnViewZoom() 
{
	ClearEvent();

	SetEvent(CPGLEventPtr(new CPGLZoomEvent));
}


void CPGLDialog::OnViewZoombox() 
{
	ClearEvent();

	SetEvent(CPGLEventPtr(new CPGLZoomRegionEvent));
}

void CPGLDialog::OnViewRefreshaxis() 
{
	if (!m_pRegion)
		return;

try
{
	m_pRegion->RefreshView(m_GDIpInterface, true, true);
}
catch(std::exception const& e)
{
    AfxMessageBox(CString("An exception has occured:") + e.what());
}

	SetDirty();
}

void CPGLDialog::OnViewProperties() 
{
	CPGLAllPropsDlg allDlg;

	allDlg.SetRegion(m_pRegion);
	allDlg.DoModal();

	m_GDIpHelper.PostRefresh();
	//updating view
	SetDirty();

}

void CPGLDialog::OnUpdatePglViewZoom(CCmdUI* pCmdUI) 
{
	if (!m_pEvent)
		pCmdUI->SetCheck(FALSE);
	else
		pCmdUI->SetCheck( m_pEvent->IsKindOf( PGLMFC_RUNTIME_CLASS(CPGLZoomEvent)) );
}

void CPGLDialog::OnUpdatePglViewPan(CCmdUI* pCmdUI) 
{
	if (!m_pEvent)
		pCmdUI->SetCheck(FALSE);
	else
		pCmdUI->SetCheck( m_pEvent->IsKindOf( PGLMFC_RUNTIME_CLASS(CPGLPanEvent)) );
}

void CPGLDialog::OnUpdatePglViewZoombox(CCmdUI* pCmdUI) 
{
	if (!m_pEvent)
		pCmdUI->SetCheck(FALSE);
	else
		pCmdUI->SetCheck( m_pEvent->IsKindOf( PGLMFC_RUNTIME_CLASS(CPGLZoomRegionEvent)) );
}

void CPGLDialog::OnViewZoomAll() 
{
	if (!m_pRegion)
		return;
try
{
	// zooming m_pRegion extents
	m_pRegion->ZoomAll(m_GDIpInterface,TRUE);
}
catch(std::exception const& e)
{
    AfxMessageBox(CString("An exception has occured:") + e.what());
}

	SetDirty();
}

void CPGLDialog::OnClose() 
{
	PGL_TRACE(_T("PGL-GraphBitDlg: Closing dialog\n"));
	CDialogEx::OnClose();
}

void CPGLDialog::OnDestroy() 
{
	PGL_TRACE(_T("PGL-GraphBitDlg: Destroying dialog\n"));
	CDialogEx::OnDestroy();

	m_GDIpHelper.Destroy();

	m_pRegion.reset();
	m_pEvent.reset();

	if (m_pDialogManager)
	{
		m_pDialogManager->Remove(this);
	}
}


void CPGLDialog::OnFileSave() 
{
	if (!m_pRegion)
		return;

	static TCHAR szFilter[] = _T("XML (*.xml)|*.xml|Zipped XML (*.xmlz)|*.xmlz||");

	// pFileDlg...
	CFileDialog pFileDlg(
		FALSE /* open */,
		_T("xml")	/* default extension */,
		_T("untitled")	/* initial pFilename in name box*/,
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING,
		szFilter);

	// Getting pFile name
	if (pFileDlg.DoModal()!=IDOK)
		return;

	// test if zipping
	if (pFileDlg.m_ofn.nFilterIndex==2)
		m_archive.SetZipping(true);
try
{
	if ( ! m_archive.Save(pFileDlg.GetPathName()))
	{
		AfxMessageBox(_T("Couldn't save file."));
	}
}
catch(std::exception const& e)
{
    AfxMessageBox(CString("An exception has occured:") + e.what());
}

}

void CPGLDialog::OnFileOpen() 
{
	if(!m_pRegion)
		return;

	static TCHAR szFilter[] = _T("XML (*.xml)|*.xml|Zipped XML (*.xmlz)|*.xmlz||");

	// pFileDlg...
	CFileDialog pFileDlg(
		TRUE /* open */,
		_T("xml")	/* default extension */,
		_T("untitled")	/* initial pFilename in name box*/,
		OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST,
		szFilter);

	// Getting pFile name
	if (pFileDlg.DoModal()!=IDOK)
		return;

    try
    {
	if (m_archive.Load(pFileDlg.GetPathName()))
	{
		m_uPointedRegion=0;

		CRect rect;
		GetClientRect(&rect);
		OnSize(0, rect.Width(), rect.Height());
	}
	else
	{
		AfxMessageBox(_T("Couldn't load file."));
	}
    }
    catch(std::exception const& e)
    {
        AfxMessageBox(CString("An exception has occured:") + e.what());
    }

}

void CPGLDialog::UpdateStatusBar()
{
	using namespace Gdiplus;

	CString str,strWorld;
	CString strNorm,strNormClip;
	CSize size;
	CRect rect;

	GetClientRectEx(rect);

	// get mouse position
	if ( !m_bStatusBar)
		return;
	//////////////////////////////////////////////////////////////////////
	// Getting pointed region...
	if (m_uPointedRegion)
	{
		CPGLRegionStPtr p=CPGLRegionPoolSingleton::Find(m_uPointedRegion);
		if (p)
			str=p->GetName();
	}
	else
	{
		str=_T("No region");
	}
	m_CSBCtrlStatus.SetPaneText(1, str);
	
	ScopedWindowDC sdc( &m_CSBCtrlStatus );
	if (!sdc)
		return;

try
{

	// computing size...
	size=sdc.GetDC()->GetOutputTextExtent(str, str.GetLength() );
	// resize pane...
	m_CSBCtrlStatus.SetPaneInfo(1, m_CSBCtrlStatus.GetItemID(1), SBPS_NORMAL, size.cx);
	
	///////////////////////////////////////////////////////////////////////
	// Mouse position
	int curx,cury;
	m_mouse.GetLeftLastPos(curx, cury);
	POINT point;
	point.x=curx;
	point.y=cury; 
	str.Format(_T("(%3d,%3d)"), point.x, point.y);
	m_CSBCtrlStatus.SetPaneText(2, str);
	
	// computing size...
	size=sdc.GetDC()->GetOutputTextExtent(str, str.GetLength() );
	// resize pane...
	m_CSBCtrlStatus.SetPaneInfo(2, m_CSBCtrlStatus.GetItemID(2), SBPS_NORMAL, size.cx);

	//////////////////////////////////////////////////////////////////////////
	// World position
	if (!m_uPointedRegion)
	{
		strWorld=_T("(--,--)");
//		strNorm=_T("(--,--)");
//		strNormClip=_T("(--,--)");
	}
	else
	{
		CRect rectFull;
		GetClientRect(&rectFull);
		CClientDC dc(this);
		Graphics graphics(dc.m_hDC);
		m_GDIpInterface.SetGraphics(&graphics);
		m_GDIpInterface.BeginPaint(dc.m_hDC);
			m_pRegion->PushWorldClipBBox(m_GDIpInterface);
				strWorld.Format( _T("(%3.3g,%3.3g)"),m_GDIpInterface.BBToWorldx(point.x), 
					m_GDIpInterface.BBToWorldy(rectFull.Height()-GetToolBarHeight()-point.y) );
/*				strNorm.Format( _T("(%3.3g,%3.3g)"),m_GDIpInterface.BBToNormx(point.x), 
					m_GDIpInterface.BBToNormy(point.y) );
				strNormClip.Format( _T("(%3.3g,%3.3g)"),m_GDIpInterface.BBToNormClipx(point.x), 
					m_GDIpInterface.BBToNormClipy(point.y) );
*/
			m_pRegion->PopWorldClipBBox(m_GDIpInterface);
		m_GDIpInterface.EndPaint();
	}
	m_CSBCtrlStatus.SetPaneText(3, strWorld);
		// computing size...
	size=sdc.GetDC()->GetOutputTextExtent(strWorld, strWorld.GetLength() );
	// resize pane...
	m_CSBCtrlStatus.SetPaneInfo(3, m_CSBCtrlStatus.GetItemID(3), SBPS_NORMAL, size.cx);


	///////////////////////////////////////////////////////////////////////
	// Client size
	str.Format(_T("%dx%d"), rect.Width(), rect.Height());
	m_CSBCtrlStatus.SetPaneText(4, str);

	// computing size...
	size=sdc.GetDC()->GetOutputTextExtent(str, str.GetLength() );

	// resize pane...
	m_CSBCtrlStatus.SetPaneInfo(4, m_CSBCtrlStatus.GetItemID(4), SBPS_NORMAL, size.cx);

}
catch( std::exception const& e)
{
    AfxMessageBox(CString("An exception has occured: ") + e.what() );
}

}

void CPGLDialog::OnFilePrint() 
{
    CDC dc;
    CPrintDialog printDlg(FALSE);

	if (!m_pRegion)
		return;

    if (printDlg.DoModal() == IDCANCEL)     // Get printer settings from user
        return;

    dc.Attach(printDlg.GetPrinterDC());     // Get and attach a printer DC
    dc.m_bPrinting = TRUE;

    CString strTitle;                       // Get the application title
    strTitle.LoadString(AFX_IDS_APP_TITLE);

    DOCINFO di;                             // Initialise print document details
    ::ZeroMemory (&di, sizeof (DOCINFO));
    di.cbSize = sizeof (DOCINFO);
    di.lpszDocName = strTitle;

try
{
    BOOL bPrintingOK = dc.StartDoc(&di);    // Begin a new print job

	// creating printer
	CPGLPrinter printer(&(*m_pRegion));

	CPrintInfo Info;

	Info.m_pPD=&printDlg;
	printer.Print(&dc, &Info);
	Info.m_pPD=NULL;

    if (bPrintingOK)
        dc.EndDoc();                        // end a print job
    else
        dc.AbortDoc();                      // abort job.

	// detach DC...
	dc.Detach();
    dc.DeleteDC();                          // delete the printer DC

	m_uPointedRegion=NULL;
}
catch( std::exception const& e)
{
    AfxMessageBox(CString("An exception has occured: ") + e.what() );
}

}

void CPGLDialog::OnEditCopytoclipboard() 
{
	if (!m_pRegion)
		return;

	CRect rect;
	GetClientRectEx(rect);

	m_archive.ExportToClipBoard(m_eClipboardType, false, CPGLPointU(rect.Width(), rect.Height()), this->m_hWnd);
}

void CPGLDialog::OnClipboardtypeBitmap()
{
	SetClipboardType( CPGLArchive::ClipBoardBitmap);
}

void CPGLDialog::OnClipboardtypeMetafile()
{
	SetClipboardType( CPGLArchive::ClipBoardMetafile);
}

void CPGLDialog::OnUpdateClipboardtypeBitmap(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck( GetClipboardType() == CPGLArchive::ClipBoardBitmap );
}

void CPGLDialog::OnUpdateClipboardtypeMetafile(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck( GetClipboardType() == CPGLArchive::ClipBoardMetafile );
}


void CPGLDialog::SetRegion(CPGLRegionPtr pRegion)	
{	
	m_pRegion=pRegion; 
	m_uPointedRegion=NULL;

	m_GDIpHelper.SetRegion(pRegion);
	if (!pRegion)
		m_archive.SetRegion(CPGLRegionStPtr());
	else
		m_archive.SetRegion(pRegion);
};

void CPGLDialog::OnViewAntialiasingText() 
{
	using namespace gfxinterface;

	DWORD dwRenderOption = m_GDIpInterface.GetRenderOption();

	if ( dwRenderOption & CGfxInterface::RenderOptionNoTextAntiAlias)
		m_GDIpInterface.SetRenderOption( ~(~dwRenderOption | CGfxInterface::RenderOptionNoTextAntiAlias) );
	else
		m_GDIpInterface.SetRenderOption( dwRenderOption | CGfxInterface::RenderOptionNoTextAntiAlias);

	SetDirty();
	InvalidateRect(NULL,FALSE);

}

void CPGLDialog::OnUpdateViewAntialiasingText(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck( !(m_GDIpInterface.GetRenderOption() & gfxinterface::CGfxInterface::RenderOptionNoTextAntiAlias) );
}

void CPGLDialog::OnViewAntialiasingGraphics() 
{
	using namespace gfxinterface;

	DWORD dwRenderOption = m_GDIpInterface.GetRenderOption();

	if ( dwRenderOption & CGfxInterface::RenderOptionNoAntiAlias)
		m_GDIpInterface.SetRenderOption( ~(~dwRenderOption | CGfxInterface::RenderOptionNoAntiAlias) );
	else
		m_GDIpInterface.SetRenderOption( dwRenderOption | CGfxInterface::RenderOptionNoAntiAlias);

	SetDirty();
	InvalidateRect(NULL,FALSE);	
}

void CPGLDialog::OnUpdateViewAntialiasingGraphics(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck( !(m_GDIpInterface.GetRenderOption() & gfxinterface::CGfxInterface::RenderOptionNoAntiAlias) );
}

void CPGLDialog::OnViewAntialiasingCubictextureinterpolation() 
{
	using namespace gfxinterface;

	DWORD dwRenderOption = m_GDIpInterface.GetRenderOption();

	if ( dwRenderOption & CGfxInterface::RenderOptionNoBiCubicInterpolation)
		m_GDIpInterface.SetRenderOption( ~(~dwRenderOption | CGfxInterface::RenderOptionNoBiCubicInterpolation) );
	else
		m_GDIpInterface.SetRenderOption( dwRenderOption | CGfxInterface::RenderOptionNoBiCubicInterpolation);

	SetDirty();
	InvalidateRect(NULL,FALSE);	
}

void CPGLDialog::OnUpdateViewAntialiasingCubictextureinterpolation(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck( !(m_GDIpInterface.GetRenderOption() & gfxinterface::CGfxInterface::RenderOptionNoBiCubicInterpolation) );
}

void CPGLDialog::SetEvent( CPGLEventPtr pEvent)
{
	ClearEvent();

	m_pEvent = pEvent;

	if( !m_pEvent)
		return;

	m_pEvent->SetParent(this);
	m_pEvent->SetGfx( &m_GDIpInterface);
	m_pEvent->SetRegion(m_uPointedRegion);
	m_pEvent->SetMouse(&m_mouse);
	m_pEvent->SetHelper(&m_GDIpHelper);
}

void CPGLDialog::ClearEvent()
{
	m_pEvent.reset();
}

void CPGLDialog::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// handling event
	if (m_pEvent)
		m_pEvent->OnKeyDown(nChar,nRepCnt,nFlags);
	
	CDialogEx::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CPGLDialog::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// handling event
	if (m_pEvent)
		m_pEvent->OnKeyUp(nChar,nRepCnt,nFlags);
	
	CDialogEx::OnKeyUp(nChar, nRepCnt, nFlags);
}

BOOL CPGLDialog::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	// handling event
	if (m_pEvent)
		m_pEvent->OnMouseWheel(nFlags,zDelta,pt);
	
	return CDialogEx::OnMouseWheel(nFlags, zDelta, pt);
}

void CPGLDialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// handling event
	if (m_pEvent)
		m_pEvent->OnHScroll(nSBCode,nPos,pScrollBar);
	
	CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CPGLDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// handling event
	if (m_pEvent)
		m_pEvent->OnVScroll(nSBCode,nPos,pScrollBar);
	
	CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CPGLDialog::OnFigureImportcsvfile() 
{
	static TCHAR BASED_CODE szFilter[] = _T("Comma Separated Values Files (*.csv)|*.csv|All Files (*.*)|*.*||");
	bool bLoaded=false;
	
	if (!m_pRegion)
		SetRegion(CPGLRegionPtr(new CPGLRegion));

	CFileDialog fileDlg(TRUE,NULL,NULL,OFN_ALLOWMULTISELECT ,szFilter);

	const size_t n=80096;
	fileDlg.m_ofn.nMaxFile=n;
	TCHAR szFileNameBuffer[n]={'\0'};

	fileDlg.m_ofn.lpstrFile=szFileNameBuffer;

	if (fileDlg.DoModal() != IDOK)
		return;

	BeginWaitCursor();

try
{
	LPCTSTR szFileName;
	CString sDirectory;
	// getting directory...
	TRACE(szFileNameBuffer);
	sDirectory=szFileNameBuffer;
	// getting file...
	szFileName = szFileNameBuffer+_tcslen(szFileNameBuffer);
	szFileName++;

	if (!_tcslen(szFileName))
	{
		// only one file seleted
		if(m_pRegion->LoadCSVFile( sDirectory ))
			bLoaded=true;		
	}

	sDirectory+='\\';
	while( _tcslen(szFileName))
	{
		// getting 
		if(m_pRegion->LoadCSVFile( sDirectory+szFileName ))
			bLoaded=true;

		// finding next file
		szFileName = _tcschr(szFileName,'\0');
		szFileName++;
	}
	

	m_pRegion->AddLegend();
	
	// redraw....
	CClientDC dc(this);
	Gdiplus::Graphics graphics(dc.m_hDC);
	m_GDIpInterface.SetGraphics(&graphics);
	m_GDIpInterface.BeginPaint(dc.m_hDC);
			m_pRegion->ZoomAll(m_GDIpInterface,true);
	m_GDIpInterface.EndPaint();	
				
	PostResize();
	SetDirty();
}
catch( std::exception const& e)
{
    AfxMessageBox(CString("An exception has occured: ") + e.what() );
}

EndWaitCursor();

}

void CPGLDialog::OnEditClearchart() 
{
	if (!m_pRegion)
		return;

	m_pRegion->DeleteAllObjects();

	SetDirty();
}

void CPGLDialog::OnAboutAbout() 
{
	CPGLAbout about;
	
	about.DoModal();
}

BOOL CPGLDialog::OnEraseBkgnd(CDC* pDC)
{
    if (m_pRegion)	
        return TRUE;
    else
        return CDialogEx::OnEraseBkgnd(pDC);
}
